/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.wdb.domain;

import org.vacoor.nothing.wdb.util.Jdbcs;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 */
public class DbTable {
    public static final String TAB_TY_TAB = "TABLE";
    public static final String TAB_TY_VIEW = "VIEW";
    public static final String TAB_TY_SYNONYM = "SYMONYM";

    final DbSchema schema;
    final String name;
    final String type;
    final String remarks;

    DbTable(DbSchema schema, String name, String type, String remarks) {
        this.schema = schema;
        this.name = name;
        this.type = type;
        this.remarks = remarks;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public String getRemarks() {
        return remarks;
    }

    public boolean isView() {
        return TAB_TY_VIEW.equals(type);
    }

    public boolean isSymonym() {
        return TAB_TY_SYNONYM.equals(type);
    }

    public DbColumn[] getColumns() throws SQLException {
        return readColumns(schema.dbMeta, schema.name, name, null);
    }

    DbColumn[] readColumns(DatabaseMetaData dbMeta, String schema, String tabName, String colName) throws SQLException {
        List<DbColumn> dbColumns = new ArrayList<DbColumn>();

        ResultSet columns = dbMeta.getColumns(null, schema, tabName, colName);
        while (columns.next()) {
            int position = columns.getInt("ORDINAL_POSITION");
            String name = columns.getString("COLUMN_NAME");
            String type = columns.getString("TYPE_NAME");

            int size = columns.getInt("COLUMN_SIZE");
            if (size > 0) {
                type += "(" + size;
                int prec = columns.getInt("DECIMAL_DIGITS");
                if (prec > 0) {
                    type += ", " + prec;
                }
                type += ")";
            }

            boolean nullable = DatabaseMetaData.columnNullable == columns.getInt("NULLABLE");
            Object colDefault = "Can't read";
            try {
                /*-
                 * oracle APEX_030200.WWV_COLUMN_EXCEPTIONS.OBSOLETE_DATE
                  * 读取会抛出异常 Stream is Closed
                  * 测试下 Oracle SQL Developer 读取也有问题(null 显示为"(null)", 但是这个字段为 "null", 也无法修改)
                 */
                colDefault = columns.getObject("COLUMN_DEF");
            } catch (SQLException ignore) {
                // ignore
                // LOG.warn
            }
            String remarks = columns.getString("REMARKS");

            dbColumns.add(new DbColumn(this, position, name, type, nullable, colDefault, remarks));
        }
        Jdbcs.close(columns);
        return dbColumns.toArray(new DbColumn[dbColumns.size()]);
    }

    @Override
    public String toString() {
        return schema + " - T#" + name + "(" + type + ")";
    }
}
